/*
 * @Author: Clark
 * @Email: haixuanwoTxh@gmail.com
 * @Date: 2023-07-08 22:12:28
 * @LastEditors: Clark
 * @LastEditTime: 2023-07-15 20:40:19
 * @Description: file content
 */
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#include "hzk16.h"

static int fd_hzk16;
static struct stat hzk_stat;
static unsigned char *hzkmem;

bool init_hzk(char *hzkName)
{
    fd_hzk16 = open(hzkName, O_RDONLY);
	if (fd_hzk16 < 0)
	{
		printf("can't open HZK16\n");
		return false;
	}

	if(fstat(fd_hzk16, &hzk_stat))
	{
		printf("can't get fstat\n");
		return false;
	}

	hzkmem = (unsigned char *)mmap(NULL , hzk_stat.st_size, PROT_READ, MAP_SHARED, fd_hzk16, 0);
	if (hzkmem == (unsigned char *)-1)
	{
		printf("can't mmap for hzk16\n");
		return false;
	}

    return true;
}

unsigned char *get_font_data(unsigned char *gbkCode, uint32_t font)
{
    unsigned int area  = gbkCode[0] - 0xA1;
	unsigned int where = gbkCode[1] - 0xA1;
	return (hzkmem + (area * 94 + where)*font*font/8);
}

unsigned char *get_16x16_font_data(unsigned char *gbkCode)
{
    unsigned int area  = gbkCode[0] - 0xA1;
	unsigned int where = gbkCode[1] - 0xA1;
	return (hzkmem + (area * 94 + where)*32);
}

void lcd_put_16x16_chinese(int x, int y, unsigned char *dots)
{
    extern void lcd_put_pixel(int x, int y, unsigned int color);
	unsigned char byte;

	int i, j, b;
	for (i = 0; i < 16; i++)
		for (j = 0; j < 2; j++)
		{
			byte = dots[i*2 + j];
			for (b = 7; b >=0; b--)
			{
				if (byte & (1<<b))
				{
					/* show */
					lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */
				}
				else
				{
					/* hide */
					lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */
				}
			}
		}

}

void lcd_put_chinese(int x, int y, unsigned char *dots, int fontSize)
{
    extern void lcd_put_pixel(int x, int y, unsigned int color);
	unsigned char byte;

    printf("T %s x[%d] y[%d]\n", __func__, x, y);

	int i, j, b;
	for (i = 0; i < fontSize; i++)
		for (j = 0; j < fontSize/8; j++)
		{
			byte = dots[i*fontSize/8 + j];
			for (b = 7; b >=0; b--)
			{
				if (byte & (1<<b))
				{
					/* show */
					lcd_put_pixel(x+j*8+7-b, y+i, 0xffffff); /* 白 */
				}
				else
				{
					/* hide */
					lcd_put_pixel(x+j*8+7-b, y+i, 0); /* 黑 */
				}
			}
		}
}

static char ConvertChar(char u8Inchar)
{
    u8Inchar = (char) ((u8Inchar << 4) + (u8Inchar >> 4));
    u8Inchar = ((u8Inchar & 0x33) << 2) + ((u8Inchar & 0xCC) >> 2);
    u8Inchar = ((u8Inchar & 0x55) << 1) + ((u8Inchar & 0xAA) >> 1);
    return u8Inchar;
}

void rotate_180_lcd_put_chinese(int x, int y, unsigned char *dots, int fontSize)
{
    uint32_t dotsSize = fontSize*fontSize/8;
    uint8_t *rotateDots = calloc(1, dotsSize);
    size_t i;

    for (i = 0; i < dotsSize; i++)
    {
        rotateDots[i] =  ConvertChar(dots[dotsSize - 1 - i]);
    }

    lcd_put_chinese(100, 100,  rotateDots, fontSize);
    free(rotateDots);
}

void print_hzK_char(char *mat, uint32_t fontSize)
{
	int i, j, k;
	for (j = 0; j < fontSize; j++)               /*横向有4个字节，循环判断每个字节的*/
    {
		for (k = 0; k < fontSize/8; k++)         /*每个字节有8位，循环判断每位是否为1*/
		{
			for (i = 0; i < 8; i++)              /*32x32点阵汉字，一共有32行*/
			{
				if (mat[j*fontSize/8+k] & (0x80 >> i))   /*测试当前位是否为1*/
					printf("*");                /*为1的显示为字符c1*/
				else
    				printf(" ");                /*为0的显示为字符c2*/
			}
		}
        printf("\n");                           /*输完一行以后，进行换行*/
    }
}

void print_hzk_clockwise_rotate_90(char *mat, uint32_t fontSize)
{
	int i, j, k;
	for (j = 0; j < fontSize / 8; j++)          /*横向有4个字节，循环判断每个字节的*/
    {
		for (k = 0; k < 8; k++)                 /*每个字节有8位，循环判断每位是否为1*/
		{
			for (i = 0; i < fontSize; i++)      /*32x32点阵汉字，一共有32行*/
			{
				if (mat[i * fontSize / 8 - j - 1] & (0x01 << k)) /*测试当前位是否为1*/
					printf("*");    /*为1的显示为字符c1*/
				else
    				printf(" ");    /*为0的显示为字符c2*/
			}
			printf("\n");                       /*输完一行以后，进行换行*/
		}
	}

}

void print_hzk_anticlockwise_rotate_90(char *mat, uint32_t fontSize)
{
	int i, j, k;
	for (j = 0; j < fontSize / 8; j++)          /*横向有4个字节，循环判断每个字节的*/
    {
		for (k = 0; k < 8; k++)                 /*每个字节有8位，循环判断每位是否为1*/
		{
			for (i = 0; i < fontSize; i++)      /*32x32点阵汉字，一共有32行*/
			{
				if (mat[(fontSize - 1 - i) * fontSize / 8 + j] & (0x80 >> k)) /*测试当前位是否为1*/
					printf("*");    /*为1的显示为字符c1*/
				else
    				printf(" ");    /*为0的显示为字符c2*/
			}
			printf("\n");                       /*输完一行以后，进行换行*/
		}
	}
}

unsigned char *get_32x32_hzk_code(unsigned char *gbkCode)
{
    #define FONTSIZE 32

	unsigned char q, w;
	unsigned long offset;

	/*区码=内码(高字节)-160  位码=内码(低字节)-160*/
	q     = *(gbkCode) - 0xa0;           /*10进制的160等于16进制的A0*/
	w     = *(gbkCode + 1) - 0xa0;       /*获得区码与位码*/
	offset = (94 * (q - 1) + (w - 1)) * FONTSIZE * FONTSIZE / 8; /*计算该汉字在字库中偏移量*/

    return (hzkmem + offset);
}
